`ifndef MULT16_SIMPLE_V
`define MULT16_SIMPLE_V

`include "Add16.v"

module Mult16_Simple(
    input [15:0] a, b,       // 16位有符号被乘数和乘数
    output [31:0] product    // 32位有符号乘积
);
    
    // 处理符号
    wire a_sign, b_sign, result_sign;
    assign a_sign = a[15];
    assign b_sign = b[15];
    assign result_sign = a_sign ^ b_sign;  // 结果符号
    
    // 取绝对值
    wire [15:0] a_abs, b_abs;
    wire [15:0] a_neg, b_neg;
    wire a_cout, b_cout;
    
    // 计算a的绝对值
    Add16 calc_a_neg(~a, 16'h0000, 1'b1, a_neg, a_cout);
    assign a_abs = a_sign ? a_neg : a;
    
    // 计算b的绝对值
    Add16 calc_b_neg(~b, 16'h0000, 1'b1, b_neg, b_cout);
    assign b_abs = b_sign ? b_neg : b;
    
    // 部分积累加器 - 我们需要实现移位相加
    // 为了简化，我们手动展开16次移位相加
    
    wire [31:0] shifted_a [15:0];  // a左移i位的结果
    wire [31:0] partial_sum [16:0]; // 累加的部分和
    wire [15:0] carry_out;
    
    // 生成a的各种移位版本
    assign shifted_a[0]  = {16'b0, a_abs};           // a << 0
    assign shifted_a[1]  = {15'b0, a_abs, 1'b0};    // a << 1
    assign shifted_a[2]  = {14'b0, a_abs, 2'b0};    // a << 2
    assign shifted_a[3]  = {13'b0, a_abs, 3'b0};    // a << 3
    assign shifted_a[4]  = {12'b0, a_abs, 4'b0};    // a << 4
    assign shifted_a[5]  = {11'b0, a_abs, 5'b0};    // a << 5
    assign shifted_a[6]  = {10'b0, a_abs, 6'b0};    // a << 6
    assign shifted_a[7]  = {9'b0,  a_abs, 7'b0};    // a << 7
    assign shifted_a[8]  = {8'b0,  a_abs, 8'b0};    // a << 8
    assign shifted_a[9]  = {7'b0,  a_abs, 9'b0};    // a << 9
    assign shifted_a[10] = {6'b0,  a_abs, 10'b0};   // a << 10
    assign shifted_a[11] = {5'b0,  a_abs, 11'b0};   // a << 11
    assign shifted_a[12] = {4'b0,  a_abs, 12'b0};   // a << 12
    assign shifted_a[13] = {3'b0,  a_abs, 13'b0};   // a << 13
    assign shifted_a[14] = {2'b0,  a_abs, 14'b0};   // a << 14
    assign shifted_a[15] = {1'b0,  a_abs, 15'b0};   // a << 15
    
    // 初始部分和为0
    assign partial_sum[0] = 32'b0;
    
    // 32位加法器实现（使用两个16位加法器）
    // 根据b的每一位决定是否添加对应的移位值
    
    // bit 0
    wire [31:0] add_input_0 = b_abs[0] ? shifted_a[0] : 32'b0;
    Add16 add_0_low (partial_sum[0][15:0],  add_input_0[15:0],  1'b0,         partial_sum[1][15:0],  carry_out[0]);
    Add16 add_0_high(partial_sum[0][31:16], add_input_0[31:16], carry_out[0], partial_sum[1][31:16], );
    
    // bit 1
    wire [31:0] add_input_1 = b_abs[1] ? shifted_a[1] : 32'b0;
    Add16 add_1_low (partial_sum[1][15:0],  add_input_1[15:0],  1'b0,         partial_sum[2][15:0],  carry_out[1]);
    Add16 add_1_high(partial_sum[1][31:16], add_input_1[31:16], carry_out[1], partial_sum[2][31:16], );
    
    // bit 2
    wire [31:0] add_input_2 = b_abs[2] ? shifted_a[2] : 32'b0;
    Add16 add_2_low (partial_sum[2][15:0],  add_input_2[15:0],  1'b0,         partial_sum[3][15:0],  carry_out[2]);
    Add16 add_2_high(partial_sum[2][31:16], add_input_2[31:16], carry_out[2], partial_sum[3][31:16], );
    
    // bit 3
    wire [31:0] add_input_3 = b_abs[3] ? shifted_a[3] : 32'b0;
    Add16 add_3_low (partial_sum[3][15:0],  add_input_3[15:0],  1'b0,         partial_sum[4][15:0],  carry_out[3]);
    Add16 add_3_high(partial_sum[3][31:16], add_input_3[31:16], carry_out[3], partial_sum[4][31:16], );
    
    // bit 4
    wire [31:0] add_input_4 = b_abs[4] ? shifted_a[4] : 32'b0;
    Add16 add_4_low (partial_sum[4][15:0],  add_input_4[15:0],  1'b0,         partial_sum[5][15:0],  carry_out[4]);
    Add16 add_4_high(partial_sum[4][31:16], add_input_4[31:16], carry_out[4], partial_sum[5][31:16], );
    
    // bit 5
    wire [31:0] add_input_5 = b_abs[5] ? shifted_a[5] : 32'b0;
    Add16 add_5_low (partial_sum[5][15:0],  add_input_5[15:0],  1'b0,         partial_sum[6][15:0],  carry_out[5]);
    Add16 add_5_high(partial_sum[5][31:16], add_input_5[31:16], carry_out[5], partial_sum[6][31:16], );
    
    // bit 6
    wire [31:0] add_input_6 = b_abs[6] ? shifted_a[6] : 32'b0;
    Add16 add_6_low (partial_sum[6][15:0],  add_input_6[15:0],  1'b0,         partial_sum[7][15:0],  carry_out[6]);
    Add16 add_6_high(partial_sum[6][31:16], add_input_6[31:16], carry_out[6], partial_sum[7][31:16], );
    
    // bit 7
    wire [31:0] add_input_7 = b_abs[7] ? shifted_a[7] : 32'b0;
    Add16 add_7_low (partial_sum[7][15:0],  add_input_7[15:0],  1'b0,         partial_sum[8][15:0],  carry_out[7]);
    Add16 add_7_high(partial_sum[7][31:16], add_input_7[31:16], carry_out[7], partial_sum[8][31:16], );
    
    // bit 8
    wire [31:0] add_input_8 = b_abs[8] ? shifted_a[8] : 32'b0;
    Add16 add_8_low (partial_sum[8][15:0],  add_input_8[15:0],  1'b0,         partial_sum[9][15:0],  carry_out[8]);
    Add16 add_8_high(partial_sum[8][31:16], add_input_8[31:16], carry_out[8], partial_sum[9][31:16], );
    
    // bit 9
    wire [31:0] add_input_9 = b_abs[9] ? shifted_a[9] : 32'b0;
    Add16 add_9_low (partial_sum[9][15:0],  add_input_9[15:0],  1'b0,         partial_sum[10][15:0], carry_out[9]);
    Add16 add_9_high(partial_sum[9][31:16], add_input_9[31:16], carry_out[9], partial_sum[10][31:16], );
    
    // bit 10
    wire [31:0] add_input_10 = b_abs[10] ? shifted_a[10] : 32'b0;
    Add16 add_10_low (partial_sum[10][15:0],  add_input_10[15:0],  1'b0,          partial_sum[11][15:0], carry_out[10]);
    Add16 add_10_high(partial_sum[10][31:16], add_input_10[31:16], carry_out[10], partial_sum[11][31:16], );
    
    // bit 11
    wire [31:0] add_input_11 = b_abs[11] ? shifted_a[11] : 32'b0;
    Add16 add_11_low (partial_sum[11][15:0],  add_input_11[15:0],  1'b0,          partial_sum[12][15:0], carry_out[11]);
    Add16 add_11_high(partial_sum[11][31:16], add_input_11[31:16], carry_out[11], partial_sum[12][31:16], );
    
    // bit 12
    wire [31:0] add_input_12 = b_abs[12] ? shifted_a[12] : 32'b0;
    Add16 add_12_low (partial_sum[12][15:0],  add_input_12[15:0],  1'b0,          partial_sum[13][15:0], carry_out[12]);
    Add16 add_12_high(partial_sum[12][31:16], add_input_12[31:16], carry_out[12], partial_sum[13][31:16], );
    
    // bit 13
    wire [31:0] add_input_13 = b_abs[13] ? shifted_a[13] : 32'b0;
    Add16 add_13_low (partial_sum[13][15:0],  add_input_13[15:0],  1'b0,          partial_sum[14][15:0], carry_out[13]);
    Add16 add_13_high(partial_sum[13][31:16], add_input_13[31:16], carry_out[13], partial_sum[14][31:16], );
    
    // bit 14
    wire [31:0] add_input_14 = b_abs[14] ? shifted_a[14] : 32'b0;
    Add16 add_14_low (partial_sum[14][15:0],  add_input_14[15:0],  1'b0,          partial_sum[15][15:0], carry_out[14]);
    Add16 add_14_high(partial_sum[14][31:16], add_input_14[31:16], carry_out[14], partial_sum[15][31:16], );
    
    // bit 15
    wire [31:0] add_input_15 = b_abs[15] ? shifted_a[15] : 32'b0;
    Add16 add_15_low (partial_sum[15][15:0],  add_input_15[15:0],  1'b0,          partial_sum[16][15:0], carry_out[15]);
    Add16 add_15_high(partial_sum[15][31:16], add_input_15[31:16], carry_out[15], partial_sum[16][31:16], );
    
    // 如果结果应该是负数，则取二补数
    wire [31:0] result_neg;
    wire neg_cout_low, neg_cout_high;
    
    Add16 neg_result_low (~partial_sum[16][15:0],  16'h0000, 1'b1,          result_neg[15:0],  neg_cout_low);
    Add16 neg_result_high(~partial_sum[16][31:16], 16'h0000, neg_cout_low, result_neg[31:16], neg_cout_high);
    
    assign product = result_sign ? result_neg : partial_sum[16];
    
endmodule

`endif
